package com.googlecode.continuity.plugin.project.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.ui.*;
import com.googlecode.continuity.core.client.CoreGWT;
import com.googlecode.continuity.core.client.GWTExternal;
import com.googlecode.continuity.core.client.UIEntryPoint;
import com.googlecode.continuity.plugin.codecomment.client.CodeCommentScreen;
import com.googlecode.continuity.plugin.codecomment.client.CodePointer;
import com.googlecode.continuity.plugin.gwtext.client.ErrorBox;
import com.googlecode.continuity.plugin.gwtext.client.LoaderBox;
import com.googlecode.continuity.plugin.project.client.message.ProjectMessages;
import com.googlecode.continuity.plugin.svnbrowser.client.*;
import com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNDirEntryWrapper;

/**
 * TestPage
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class SourceBrowser extends UIEntryPoint {

  private int fileRequestCounter = 0;
  private SVNRepositoryHandle SVNHandle;

  private final ProjectMessages messages = (ProjectMessages) GWT.create(ProjectMessages.class);

  public void onModuleLoadUI() {
    if (DOM.getElementById("browseContainer") == null) {
      // todo: throw exception
    }

    final Label browse = new Label(messages.browseSources());
    browse.addStyleName("link");

    final SVNBrowser svnBrowser = new SVNBrowser();
    svnBrowser.setRootPrefix(GWTExternal.getProperty("projectName"));

    final PopupPanel loader = new LoaderBox(messages.loadingFile());

    AsyncCallback getProjectHandle = new AsyncCallback() {
      public void onFailure(Throwable throwable) {
        // todo: show error
      }

      public void onSuccess(Object o) {
        SVNHandle = (SVNRepositoryHandle) o;
        svnBrowser.setHandle(SVNHandle);
        svnBrowser.setPath("");
        DOM.setInnerHTML(RootPanel.get("browseContainer").getElement(), "");
        RootPanel.get("browseContainer").add(browse);
      }
    };

    browse.addClickListener(new ClickListener() {
      public void onClick(Widget widget) {
        svnBrowser.show();
      }
    });

    final ReadSVNRPCAsync svnRPCAsync = (ReadSVNRPCAsync) CoreGWT.getRPC("ReadSVNRPCAsync");

    // listen for file browser selections
    svnBrowser.addSVNBrowserEventListener(new SVNBrowserEventListener() {
      public void onDirectorySelected(String directoryPath) {
      }

      // retrieve file contents
      public void onFileSelected(SVNDirEntryWrapper entry, String filePath) {
        final CodePointer pointer = new CodePointer();
        pointer.setUrl(entry.getURL());
        pointer.setName(entry.getName());
        pointer.setFirstLine(1);
        pointer.setVersion(entry.getRevision());

        loader.show();

        final int requestId = ++fileRequestCounter;

        // show file contents
        svnRPCAsync.getTextFileContents(SVNHandle, filePath, pointer.getVersion(), new AsyncCallback() {
          public void onFailure(Throwable throwable) {
            if (!loader.isVisible() || requestId != fileRequestCounter) {
              return;
            }
            loader.hide();
            String error = "";
            try {
              throw throwable;
            } catch (InvocationException e) {
              error = e.getMessage();
            } catch (ReadSVNException e) {
              error = e.getMessage();
            } catch (Throwable t) {
              GWT.getUncaughtExceptionHandler().onUncaughtException(t);
            }
            ErrorBox box = new ErrorBox(error);
            box.show();
          }

          public void onSuccess(Object object) {
            if (!loader.isVisible() || requestId != fileRequestCounter) {
              return;
            }
            String code = (String) object;
            CodeCommentScreen box = new CodeCommentScreen(SVNHandle, pointer, code);
            loader.hide();
            box.show();
          }
        });
      }
    });

    ((ProjectRPCAsync) CoreGWT.getRPC("ProjectRPCAsync"))
        .getRepositoryHandle(Integer.parseInt(GWTExternal.getProperty("projectID")), getProjectHandle);
  }
}